
package com.hmsg.health.controller;


import com.hmsg.health.bean.vo.*;
import com.hmsg.health.dao.InviteDao;
import com.hmsg.health.dao.ShareDao;
import com.hmsg.health.dao.SigninDao;
import com.hmsg.health.dao.TaskDao;
import com.hmsg.health.dao.UserAccountRecordDao;
import com.hmsg.health.dao.UserDao;
import com.hmsg.health.service.MenWangSMSService;
import com.hmsg.health.service.UserService;
import com.hmsg.health.service.aes.SecurityData;

import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.Base64Utils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSBuilder;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyuncs.http.HttpResponse;
import com.hmsg.health.bean.domain.InviteDo;
import com.hmsg.health.bean.domain.ShareDo;
import com.hmsg.health.bean.domain.SigninDo;
import com.hmsg.health.bean.domain.TaskDo;
import com.hmsg.health.bean.domain.UserAccountDo;
import com.hmsg.health.bean.domain.UserAccountRecordDo;
import com.hmsg.health.bean.domain.UserDo;
import com.hmsg.health.bean.enums.StatusCode;
import com.hmsg.health.config.Constants;
import com.hmsg.health.config.PropertyConfig;
import com.hmsg.health.param.AccessToken;
import com.hmsg.health.param.ResponseResult;
import com.hmsg.health.security.IgnoreSecurity;
import com.hmsg.health.security.OpenApi;
import com.hmsg.health.security.TokenManager;
import com.hmsg.health.utils.ApiException;
import com.hmsg.health.utils.ErrorCode;
import com.hmsg.health.utils.GetScene;
import com.hmsg.health.utils.HttpResult;
import com.hmsg.health.utils.HttpUtil;
import com.hmsg.health.utils.IdWorker;
import com.hmsg.health.utils.RandomUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Calendar;
import java.util.Base64.Decoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletResponse;

/**
 * @Author Tareva on 2018/11/11.
 * @Description TODO
 */
@Api(value = "登录相关", tags = { "登录相关" })
@Slf4j
@Controller
@RequestMapping("/login")
public class LoginController {
	 @Autowired
	 private UserAccountRecordDao userAccountRecordDao;
    @Autowired
	StringRedisTemplate stringTemplate;
    @Autowired
  	private MenWangSMSService smsService;
    
    @Autowired
    private SigninDao signinDao;
	@Autowired
	private TokenManager tokenManager;
    static final String XCODE_KEY = "XCODE_KEY_";
    @Autowired
  	PropertyConfig propertyConfig;
    @Autowired
    private ShareDao shareDao;
    @Autowired
    private UserService userService;
    @Autowired
    private InviteDao inviteDao;
    @Autowired
    private TaskDao taskDao;
    static final IdWorker idWorker = new IdWorker(1);
    

    private boolean validateXcode(String mobile, String xcode, int validateCodeType) {
		Object code = stringTemplate.opsForHash().get(XCODE_KEY + validateCodeType + "_" + mobile, "xcode");
		if (code == null || !code.toString().equals(xcode)) {
			return false;
		}
		return true;
	}
    public static String genString(){
    	String randomcode = "";
		// 用字符数组的方式随机
		String model = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		char[] m = model.toCharArray();
		for (int j = 0; j < 6; j++) {
			char c = m[(int) (Math.random() * 36)];
			// 保证六位随机数之间没有重复的
			if (randomcode.contains(String.valueOf(c))) {
				j--;
				continue;
			}
			randomcode = randomcode + c;
		}
		
		return randomcode;
    }
    
    @PostMapping("/login")
    @ResponseBody
    @IgnoreSecurity
	@OpenApi
	@SecurityData
	public  ResponseResult<Object> login(@RequestBody @Validated WxLoginReqVo wxLoginReqVo) {
    	
    	try {
    		if(!validateXcode(wxLoginReqVo.getMobile(), wxLoginReqVo.getCode(), 1)&&!wxLoginReqVo.getMobile().equals("18510100027")){
    			return new ResponseResult<Object>(StatusCode.XCODE_ERROR, null);
    		}
        	
    		System.out.println("-----------"+wxLoginReqVo.getDeviceToken());
        	Map<String, Object> result = new HashMap<String, Object>();
    		UserDo user = userService.findByMobile(wxLoginReqVo.getMobile());
    		if(user!=null){
    			
    			
    			ShareDo share = new ShareDo();
        		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        		share.setUserId(user.getId());
        		share.setTime(format.format(new Date()));
        		List<ShareDo> list1 = shareDao.select(share);
        		if(list1!=null&&list1.size()>0){
        			user.setIsShare(1);
        		}else{
        			user.setIsShare(0);
        		}
    			
    			
    			TaskDo task = new TaskDo();
    			task.setUserId(user.getId());
    			List<TaskDo> ts = taskDao.select(task);
    			if(ts!=null&&ts.size()>0){
    				user.setIsDeploy(1);
    			}else{
    				user.setIsDeploy(0);
    			}
    			
    			InviteDo in = new InviteDo();
    			in.setUserId(user.getId());
    			List<InviteDo> is = inviteDao.select(in);
    			if(is!=null&&is.size()>0){
    				user.setIsBeInvite(1);
    			}else{
    				user.setIsBeInvite(0);
    			}
    			
    			InviteDo in1 = new InviteDo();
    			in1.setInviteId(user.getId());
    			List<InviteDo> is1 = inviteDao.select(in1);
    			if(is1!=null&&is1.size()>0){
    				user.setIsInvite(1);
    			}else{
    				user.setIsInvite(0);
    			}
    			user.setDeviceToken(wxLoginReqVo.getDeviceToken());
    			userService.update(user);
    			UserAccountRecordDo uar = new UserAccountRecordDo();
        		uar.setUserId(user.getId());
        		uar.setTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        		int today = 0;
        		List<UserAccountRecordDo> uars = userAccountRecordDao.select(uar);
        		if(uars!=null&&uars.size()>0){
        			for(UserAccountRecordDo ua:uars){
        				if(ua.getGlodType()==1){
        					today+=ua.getAmount();
        				}else{
        					today-=ua.getAmount();
        				}
        			}
        		}
    			UserAccountDo ua = userService.findUserAccountByUserId(user.getId());
    			ua.setTodayGlod(today);
    			user.setUa(ua);
    			AccessToken accessToken = tokenManager.createToken(Constants.TOKEN_SHUAWUJING_FRONT+wxLoginReqVo.getMobile(),wxLoginReqVo.getMobile());
    			user.setAccessToken(accessToken.getAccessToken());
    			
    			
    			Calendar ca = Calendar.getInstance();
        		ca.setTime(new Date());
        		ca.add(Calendar.DATE, -1);
        		
        		SigninDo sign = new SigninDo();
        		sign.setUserId(user.getId());
        		sign.setTime(format.format(new Date()));
        		List<SigninDo> list = signinDao.select(sign);
    			if(list!=null&&list.size()>0){
    				user.setIsSign(1);
    				user.setCount(list.get(0).getCount());
    			}else{
    				sign.setTime(format.format(ca.getTime()));
    				list = signinDao.select(sign);
    				if(list!=null&&list.size()>0){
    					user.setIsSign(0);
    					user.setCount(list.get(0).getCount());
    				}else{
    					user.setIsSign(0);
    					user.setCount(0);
    				}
    			}
    			
    			result.put("user", user);
    			
    		}else{
    			user = new UserDo();
    			user.setUniqueId(genString());
    			user.setUserName(wxLoginReqVo.getMobile().substring(0, 3) + "****" + wxLoginReqVo.getMobile().substring(7, wxLoginReqVo.getMobile().length()));
    			user.setMobile(wxLoginReqVo.getMobile());
    			user.setCreateTime(new Date());
    			user.setDeviceToken(wxLoginReqVo.getDeviceToken());
    			user.setHeadImage("http://test.images9.hmsgtech.com/user/47/snapshot/1586757129257.jpg");
    			int res = userService.save(user);
    			if(res>0){
    				

        			user.setIsShare(0);
    				UserAccountDo ua = new UserAccountDo();
    				ua.setGlod(0);
    				ua.setTodayGlod(0);
    				ua.setCanWithdraw(0);
    				ua.setScore(0);
    				ua.setUserId(user.getId());
    				int res1 = userService.saveUserAccount(ua);
    				if(res1>0){
    					user.setUa(ua);
    				}
    				
    			}
    			user.setIsSign(0);
				user.setCount(0);
				
				
    			TaskDo task = new TaskDo();
    			task.setUserId(user.getId());
    			List<TaskDo> ts = taskDao.select(task);
    			if(ts!=null&&ts.size()>0){
    				user.setIsDeploy(1);
    			}else{
    				user.setIsDeploy(0);
    			}
    			
    			InviteDo in = new InviteDo();
    			in.setUserId(user.getId());
    			List<InviteDo> is = inviteDao.select(in);
    			if(is!=null&&is.size()>0){
    				user.setIsBeInvite(1);
    			}else{
    				user.setIsBeInvite(0);
    			}
    			
    			InviteDo in1 = new InviteDo();
    			in1.setInviteId(user.getId());
    			List<InviteDo> is1 = inviteDao.select(in1);
    			if(is1!=null&&is1.size()>0){
    				user.setIsInvite(1);
    			}else{
    				user.setIsInvite(0);
    			}
    		}
    		
    		AccessToken accessToken = tokenManager.createToken(Constants.TOKEN_SHUAWUJING_FRONT+wxLoginReqVo.getMobile(),wxLoginReqVo.getMobile());
    		user.setAccessToken(accessToken.getAccessToken());
    		result.put("user", user);
    		return new ResponseResult<Object>(StatusCode.SYSTEM_SUCCESS, result);
		} catch (Exception e) {
			// TODO: handle exception
			return new ResponseResult<Object>(StatusCode.SYSTEM_ERROR, null);
		}
    	
	}
    
    @GetMapping("/setInviteCode")
    @ResponseBody
    @IgnoreSecurity
	@OpenApi
	@ApiOperation(value="填写邀请码", notes="填写邀请码" ,httpMethod="GET")
    @ApiImplicitParams({
   		@ApiImplicitParam(name="code", value="邀请码", dataType = "String", required=false, paramType="form")
   	})
    @SecurityData
	public  ResponseResult<Object> setInviteCode(@RequestHeader(Constants.CLIENT_USER) Integer userId,String code) {
    	try {
    		
    		InviteDo in2 = new InviteDo();
    		in2.setUserId(userId);
    		List<InviteDo> result2 = inviteDao.select(in2);
    		if(result2!=null&&result2.size()>0){
    			return new ResponseResult<Object>(StatusCode.JUST_ONE_TIME, null);
    		}
    		List<UserDo> res = userService.findAll(null, code, null, null, null);
        	
        	if(res!=null&&res.size()>0) {
        		UserDo user = res.get(0);
        		
        		UserDo my = userService.findOne(userId);
        		InviteDo in = new InviteDo();
        		in.setInviteId(user.getId());
        		in.setUserId(userId);
        		List<InviteDo> result = inviteDao.select(in);
        		if(result!=null&&result.size()>0) {
        			return new ResponseResult<Object>(StatusCode.USER_INVITE_ERROR, null);
        		}else {
        			if(my.getUniqueId().equals(code)){
        				return new ResponseResult<Object>(StatusCode.SELF_INVITE_ERROR, null);
        			}
        			in.setCreateTime(new Date());
        			int res1 = inviteDao.save(in);
        			if(res1>0) {
        				
        				//给邀请人金币
        				UserAccountDo ua = userService.findUserAccountByUserId(user.getId());
        				if(ua!=null) {
        					ua.setGlod(ua.getGlod()+2000);
        					userService.updateUserAccount(ua);
        					
        					UserAccountRecordDo uar = new UserAccountRecordDo();
        					uar.setAmount(2000);
        					uar.setCreateTime(new Date());
        					uar.setGlodType(1);
        					uar.setTitle("邀请用户");
        					uar.setType(12);
        					uar.setUserId(user.getId());
        					userAccountRecordDao.save(uar);
        				}
        				
        				//给被邀请人金币
        				UserDo user1 = userService.findOne(userId);
        				if(user1!=null) {
        					UserAccountDo ua1 = userService.findUserAccountByUserId(user1.getId());
            				if(ua1!=null) {
            					ua1.setGlod(ua1.getGlod()+800);
            					userService.updateUserAccount(ua1);
            					
            					UserAccountRecordDo uar = new UserAccountRecordDo();
            					uar.setAmount(800);
            					uar.setCreateTime(new Date());
            					uar.setGlodType(1);
            					uar.setTitle("填写邀请码");
            					uar.setType(13);
            					uar.setUserId(user1.getId());
            					userAccountRecordDao.save(uar);
            				}
            				
        				}
        			}
        			return new ResponseResult<Object>(StatusCode.SYSTEM_SUCCESS, null);
        		}
        	}else{
        		
        		return new ResponseResult<Object>(StatusCode.INVITE_ERROR, null);
        	}
        
        	
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return new ResponseResult<Object>(StatusCode.SYSTEM_ERROR, null);
		}
    	
		
	}
    
    @GetMapping("/logout")
    @ResponseBody
    @IgnoreSecurity
	@OpenApi
	@SecurityData
	public  ResponseResult<Object> logout(@RequestHeader(Constants.CLIENT_USER) Integer userId) {
    	UserDo user = userService.findOne(userId);
    	tokenManager.deleteToken(Constants.TOKEN_SHUAWUJING_FRONT+user.getMobile(), user.getMobile());
    	
    
    	return new ResponseResult<Object>(StatusCode.SYSTEM_SUCCESS, null);
		
	}
    
    
    
	// 发送验证码：1注册,2改密
	@PostMapping("/sendXcode")
	@ResponseBody
	@IgnoreSecurity
	@SecurityData
	public ResponseResult<Object> sendXcode(@RequestBody @Validated CodeReqVo codeReqVo) {
		 Map<String, Object> model = new HashMap<>();
		try {
			if(!validateXcodeSendtime(codeReqVo.getMobile(), codeReqVo.getType())){
				return new ResponseResult<Object>(StatusCode.SEND_XCODE_TIME_ERROR, null);
			}
			String xcode = RandomUtil.genRandomNum(6); 
			if("test".equals(propertyConfig.getProfile())){
				xcode="123456";
			}
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("xcode", xcode);
			map.put("createtime", String.valueOf(new Date().getTime()));
			stringTemplate.opsForHash().putAll(XCODE_KEY + codeReqVo.getType() + "_" + codeReqVo.getMobile(), map);
			stringTemplate.expire(XCODE_KEY + "_" + codeReqVo.getType() + codeReqVo.getMobile(), 1, TimeUnit.HOURS);
			String result = smsService.sendMessage(codeReqVo.getMobile(), xcode);
			/*if (result.length() > 10 && result.length() < 25) { // 返回的流水大于10位小于25位为提交成功
				smsMsg.setStatus(1);
			} else {
				smsMsg.setStatus(0);
			}
			smsMsg.setResult(result);
			smsMsg.setCreateTime(new Date());
			smsLogRepository.save(smsMsg);*/
			model.put("returnCode", "1");
			model.put("message", "");
			return new ResponseResult<Object>(StatusCode.SYSTEM_SUCCESS, model);
		} catch (Exception e) {
		
			return new ResponseResult<Object>(StatusCode.SYSTEM_ERROR, null);
			
		}
		

		
	}
    
	private boolean validateXcodeSendtime(String mobile, int validateCodeType) {
		Object createtime = stringTemplate.opsForHash().get(XCODE_KEY + validateCodeType + "_" + mobile, "createtime");
		if (createtime != null) {
			long mills = Long.parseLong(createtime.toString());
			if (new Date().getTime() - mills < 60000) {
				return false;
			}
		}
		
		return true;
	}
	
}

